#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");

static struct completion comple; //用于保存completion的状态
struct task_struct * old_thread; //用于保存模块初始化进程

int my_function(void * argc)
{
	printk("in the kernel thread function! \n");
	printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
	printk("the value of done of the comple:%d\n", comple.done); //显示字段done的值
	//  -->  0
		
	// 唤醒之前
	printk("the state of the init function is :%ld\n", old_thread->state);



	// 显示父进程的状态
	complete(&comple);    //调用函数唤醒进程，并更改done字段的值

	printk("the value of done of the comple:%d\n", comple.done);
	// 显示函数调用之后字段done的值
	
	printk("the state of the init function is :%ld\n", old_thread->state);
	// 显示父进程的状态
	
	printk("out the kernel thread function\n");
	return 0;
}


static int __init complete_init(void)
{
	char namefrm[] = "complete.c";
	struct task_struct * result;
	long left_time;
	wait_queue_t data;
	printk("into complete_init.\n");
	old_thread = current;
	result=kthread_create_on_node(my_function, NULL, -1, namefrm); //创建新进程
	wake_up_process(result);
	init_completion(&comple);                  //初始化全局变量
	init_waitqueue_entry(&data, current); //用当前进程初始化等待队列元素
	add_wait_queue(&(comple.wait), &data); // 将当前进程加入等待队列中
	left_time = schedule_timeout_uninterruptible(1000); //使等待队列进程不可中断的等待状态
	
	
	//显示函数kernel_thread( )的返回结果
	printk("the pid of result is :%d\n", result->pid);

	//显示函数sleep_on_timeout( )的返回结果
	printk("the return result of the schedule_timeout_uninterruptible is:%ld\n", left_time);                                    
	
	printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
	printk("out complete_init.\n");
	return 0;
}

static void __exit complete_exit(void)
{
	printk("Goodbye complete\n");
}

module_init(complete_init);
module_exit(complete_exit);
